package com.duan.laugh.compute.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.duan.laugh.compute.mapper.ComputeMapper;
import com.duan.laugh.compute.pojo.entity.Compute;
import com.duan.laugh.compute.service.ComputeService;
import com.duan.laugh.compute.util.ListUtils;
import com.greenpineyu.fel.FelEngine;
import com.greenpineyu.fel.FelEngineImpl;
import com.greenpineyu.fel.context.FelContext;
import org.apache.commons.jexl3.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

@Service
public class ComputeServiceImpl extends ServiceImpl<ComputeMapper, Compute> implements ComputeService {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public void test() {
        baseMapper.test();
    }

    @Override
    public boolean updateV1() {
        return baseMapper.updateV1();
    }

    @Override
    public Integer updateList(List<Compute> list) {
        return baseMapper.updateList(list);
    }

    @Override
    public Integer updateListV1(List<Compute> list) {
        return baseMapper.updateListV1(list);
    }

    @Override
    public Integer insertList(List<Compute> list) {
        String createTableSql = "drop table if exists `compute_1`; CREATE TABLE `compute_1` LIKE `compute`";
        jdbcTemplate.execute(createTableSql);
        final List<List<Compute>> lists = ListUtils.averageAssign(list, 10000);
        lists.stream().forEach(item -> insert(item));
        return 1;
    }

    @Override
    public Integer insertListParallel(List<Compute> list) {
        String createTableSql = "drop table if exists `compute_1`; CREATE TABLE `compute_1` LIKE `compute`";
        jdbcTemplate.execute(createTableSql);
        final List<List<Compute>> lists = ListUtils.averageAssign(list, 10000);
        lists.parallelStream().forEach(item -> insert(item));
        return 1;
    }

    @Override
    public List<Compute> selectByIds(List<Long> ids) {
        return baseMapper.selectByIds(ids);
    }

    /**
     * 一万条：5932,7722,3517,4738
     * 十万条：20553，15600，18369，18148
     * @param ids
     * @return
     */
    @Override
    public List<Map<String, Object>> selectMapByIds(List<Long> ids) {
//        StringBuffer stringBuffer = new StringBuffer("select * from compute where id in (");
//        for (int i = 0 , size = ids.size();i < size; i++) {
//            if(i % 999 == 998){
//                stringBuffer.append("null) OR ID IN (").append(ids.get(i)).append(",");
//            } else{
//                stringBuffer.append(ids.get(i)).append(",");
//            }
//        }
//         String s = stringBuffer.toString();
//        s = s.substring(0, s.length()-1) + ")";
//        return jdbcTemplate.queryForList(s);
        return baseMapper.selectMapByIds(ids);
    }

    /**
     * 一万条：5489,14097,4012,4956
     * 十万条：19916，13512，11736，11739——内存表11813、13843、13658、9744
     * @param ids
     * @return
     */
    @Override
    public List<Map<String, Object>> insertByV1(List<Long> ids) {
//        String createTableSql = "drop table if exists `compute_2`; CREATE TABLE `compute_2` (id bigint ,PRIMARY KEY (`id`))";
        String createTableSql = "drop table if exists `compute_2`; CREATE temporary TABLE `compute_2` (id bigint ,PRIMARY KEY (`id`))";
        jdbcTemplate.execute(createTableSql);
        StringBuffer sql = new StringBuffer("INSERT INTO `laugh-compute`.`compute_2`(`id`) values");
        StringBuffer stringBuffer = new StringBuffer();
        ids.forEach(item -> stringBuffer.append("('").append(item).append("'),"));
        String s = stringBuffer.toString();
        s = s.endsWith(",") ? s.substring(0, s.length() - 1) : s;
        sql.append(s);
        jdbcTemplate.execute(sql.toString());

        String selectSql = "select compute.* from compute inner join compute_2 on compute.id = compute_2.id";
        return jdbcTemplate.queryForList(selectSql);
    }

    private void insert(List<Compute> list) {

        StringBuffer sql = new StringBuffer("INSERT INTO `laugh-compute`.`compute_1`(`id`, `v1`, `v2`, `v3`, `v4`, `v5`, `v6`, `v7`, `v8`, `v9`, `v10`, `v11`, `v12`, `v13`, `v14`, `v15`, `v16`, `v17`, `v18`, `v19`, `v20`, `v21`, `v22`, `v23`, `v24`) " +
                "VALUES ");
        StringBuffer stringBuffer = new StringBuffer();
        list.forEach(item -> {
            stringBuffer.append("('").append(item.getId()).append("',");
            stringBuffer.append("'").append(item.getV1()).append("',");
            stringBuffer.append("'").append(item.getV2()).append("',");
            stringBuffer.append("'").append(item.getV3()).append("',");
            stringBuffer.append("'").append(item.getV4()).append("',");
            stringBuffer.append("'").append(item.getV5()).append("',");
            stringBuffer.append("'").append(item.getV6()).append("',");
            stringBuffer.append("'").append(item.getV7()).append("',");
            stringBuffer.append("'").append(item.getV8()).append("',");
            stringBuffer.append("'").append(item.getV9()).append("',");
            stringBuffer.append("'").append(item.getV10()).append("',");
            stringBuffer.append("'").append(item.getV11()).append("',");
            stringBuffer.append("'").append(item.getV12()).append("',");
            stringBuffer.append("'").append(item.getV13()).append("',");
            stringBuffer.append("'").append(item.getV14()).append("',");
            stringBuffer.append("'").append(item.getV15()).append("',");
            stringBuffer.append("'").append(item.getV16()).append("',");
            stringBuffer.append("'").append(item.getV17()).append("',");
            stringBuffer.append("'").append(item.getV18()).append("',");
            stringBuffer.append("'").append(item.getV19()).append("',");
            stringBuffer.append("'").append(item.getV20()).append("',");
            stringBuffer.append("'").append(item.getV21()).append("',");
            stringBuffer.append("'").append(item.getV22()).append("',");
            stringBuffer.append("'").append(item.getV23()).append("',");
            stringBuffer.append("'").append(item.getV24()).append("'),");
        });
        String s = stringBuffer.toString();
        s = s.endsWith(",") ? s.substring(0, s.length() - 1) : s;
        sql.append(s);
        jdbcTemplate.execute(sql.toString());
    }

    public static void main(String[] args) {
        Long startTime = System.currentTimeMillis();
        for (int i = 0; i < 10000; i++) {
            jxel();
        }
        Long endTime = System.currentTimeMillis();
        System.out.println("用时："+(endTime - startTime) +"毫秒");
//        fel();
    }
    public static void jxel(){
        JexlEngine jexl = new JexlBuilder().create();
        //创建Context设值对象
        JexlContext jexlContext = new MapContext();
        //表达式，表达式为逻辑语句
        String expressionStr = "jibenxinchou = 6657;" +
                "yingfashouruheji=jibenxinchou+dushengzinvfei+huiminbutie+xichenfei+cainuanbutie+qitajibenxinchou+qitajixiaoxinchou+jiabanfei+yufaguanlijixiaoxinchou+yufashiyebujixiaoxinchou+yanqizhifufanhuanjine-koujibenxinchou-koujixiaoxinchou-yanqizhifukouchujine-yanqizhifuzantingjine-yanqizhifutiqujine;" +
                "gonghuihuifei=(jibenxinchou+qitajibenxinchou)*0.005;" +
                "shifaxinchou =yingfashouruheji-zhufanggongjijingerenjiaofeijine-gerensuodeshui1-gerensuodeshui2-yanglaobaoxiangerenjiaofeijine-yiliaobaoxiangerenjiaofeijine-qiyenianjingerenjiaofeijine-kouqita+tiaozhengxiang-gonghuihuifei-shiyebaoxiangerenjiaofeijine;" +
                "jibenxinchoushifa = jibenxinchou+dushengzinvfei+huiminbutie+xichenfei+cainuanbutie+qitajibenxinchou+jiabanfei-koujibenxinchou-zhufanggongjijingerenjiaofeijine-gerensuodeshui1-yanglaobaoxiangerenjiaofeijine-yiliaobaoxiangerenjiaofeijine-qiyenianjingerenjiaofeijine-gonghuihuifei-kouqita+tiaozhengxiang+bufajibenxinchou;" +
                "jixiaoxinchoushifa = qitajixiaoxinchou+yufaguanlijixiaoxinchou+yufashiyebujixiaoxinchou+yanqizhifufanhuanjine-koujixiaoxinchou-yanqizhifukouchujine-gerensuodeshui2-yanqizhifuzantingjine-yanqizhifutiqujine;";
        //输入
        jexlContext.set("dushengzinvfei", 0);
        jexlContext.set("huiminbutie", 0);
        jexlContext.set("xichenfei", 0);
        jexlContext.set("cainuanbutie", 0);
        jexlContext.set("qitajibenxinchou", 0);
        jexlContext.set("qitajixiaoxinchou", 0);
        jexlContext.set("jiabanfei", 0);
        jexlContext.set("yufaguanlijixiaoxinchou", 0);
        jexlContext.set("yufashiyebujixiaoxinchou", 0);
        jexlContext.set("koujixiaoxinchou", 0);
        jexlContext.set("yanqizhifutiqujine", 0);
        jexlContext.set("yanqizhifufanhuanjine", 0);
        jexlContext.set("yanqizhifuzantingjine", 0);
        jexlContext.set("yanqizhifukouchujine", 0);
        jexlContext.set("gerensuodeshui1", 0);
        jexlContext.set("gerensuodeshui2", 0);
        jexlContext.set("qiyenianjingerenjiaofeijine", 0);
        jexlContext.set("kouqita", 0);
        jexlContext.set("tiaozhengxiang", 0);
//        jexlContext.set("餐费补贴" , 0);
        jexlContext.set("bufajibenxinchou", 0);
//        jexlContext.set("补发绩效薪酬"  , 0);
//        jexlContext.set("年终绩效税前金额"  , 0);
//        jexlContext.set("高温补贴" , 0);
        // 考勤
        jexlContext.set("koujibenxinchou", 0);

        // 社保
        jexlContext.set("yanglaobaoxiangerenjiaofeijine", 819.76);
        jexlContext.set("zhufanggongjijingerenjiaofeijine", 1230);
        jexlContext.set("yiliaobaoxiangerenjiaofeijine", 204.94);
        jexlContext.set("shiyebaoxiangerenjiaofeijine", 0);

        // 考勤
//        jexlContext.set("事假天数", 0);
//        jexlContext.set("病假天数", 0);
//        jexlContext.set("旷工天数", 0);
//        jexlContext.set("迟到小时数", 0);
//        jexlContext.set("产假天数", 0);
        JexlScript e = jexl.createScript(expressionStr);
        //使用表达式对象开始计算
        Object o = e.execute(jexlContext);
//        System.out.println(o);
//        System.out.println("应发收入合计:" + jexlContext.get("yingfashouruheji"));
//        System.out.println("工会会费:" + jexlContext.get("gonghuihuifei"));
//        System.out.println("实发薪酬:" + jexlContext.get("shifaxinchou"));
//        System.out.println("基本薪酬实发:" + jexlContext.get("jibenxinchoushifa"));
//        System.out.println("绩效薪酬实发:" + jexlContext.get("jixiaoxinchoushifa"));
        //输出：2
    }

    public static void fel() {
        Long startTime = System.currentTimeMillis();
        FelEngine fel = new FelEngineImpl();
        FelContext jexlContext = fel.getContext();

        String expressionStr =
                "应发收入合计=基本薪酬+独生子女费+回民补贴+吸尘费+采暖补贴+其它基本薪酬+其它绩效薪酬+加班费+预发管理绩效薪酬+预发事业部绩效薪酬+延期支付返还金额-扣基本薪酬-扣绩效薪酬-延期支付扣除金额-延期支付暂停金额-延期支付提取金额;"+
                "工会会费=基本薪酬+其它基本薪酬*0.005;"+
                "实发薪酬 =应发收入合计-住房公积金个人缴费金额-个人所得税一-个人所得税二-养老保险个人缴费金额-医疗保险个人缴费金额-企业年金个人缴费金额-扣其他+调整项-工会会费-失业保险个人缴费金额;"+
                "基本薪酬实发 = 基本薪酬+独生子女费+回民补贴+吸尘费+采暖补贴+其它基本薪酬+加班费-扣基本薪酬-住房公积金个人缴费金额-个人所得税一-养老保险个人缴费金额-医疗保险个人缴费金额-企业年金个人缴费金额-工会会费-扣其他+调整项+补发基本薪酬;"+
                "绩效薪酬实发 = 其它绩效薪酬+预发管理绩效薪酬+预发事业部绩效薪酬+延期支付返还金额-扣绩效薪酬-延期支付扣除金额-个人所得税二-延期支付暂停金额-延期支付提取金额;";
        //输入
        jexlContext.set("基本薪酬", 6657);
        jexlContext.set("独生子女费", 0);
        jexlContext.set("回民补贴", 0);
        jexlContext.set("吸尘费", 0);
        jexlContext.set("采暖补贴", 0);
        jexlContext.set("其它基本薪酬", 0);
        jexlContext.set("其它绩效薪酬", 0);
        jexlContext.set("加班费", 0);
        jexlContext.set("预发管理绩效薪酬", 0);
        jexlContext.set("预发事业部绩效薪酬", 0);
        jexlContext.set("扣绩效薪酬" , 0);
        jexlContext.set("延期支付提取金额" , 0);
        jexlContext.set("延期支付返还金额" , 0);
        jexlContext.set("延期支付暂停金额" , 0);
        jexlContext.set("延期支付扣除金额" , 0);
        jexlContext.set("个人所得税一" , 0);
        jexlContext.set("个人所得税二" , 0);
        jexlContext.set("企业年金个人缴费金额" , 0);
        jexlContext.set("扣其他" , 0);
        jexlContext.set("调整项" , 0);
        jexlContext.set("餐费补贴" , 0);
        jexlContext.set("补发基本薪酬" , 0);
        jexlContext.set("补发绩效薪酬"  , 0);
        jexlContext.set("年终绩效税前金额"  , 0);
        jexlContext.set("高温补贴" , 0);
        // 考勤
        jexlContext.set("扣基本薪酬" , 0);
        jexlContext.set("养老保险个人缴费金额" , 0);
        jexlContext.set("住房公积金个人缴费金额", 0);
        jexlContext.set("医疗保险个人缴费金额", 0);
        jexlContext.set("失业保险个人缴费金额", 0);
        jexlContext.set("事假天数", 0);
        jexlContext.set("病假天数", 0);
        jexlContext.set("旷工天数", 0);
        jexlContext.set("迟到小时数", 0);
        jexlContext.set("产假天数", 0);
        Object result = fel.eval(expressionStr);

        System.out.println(result);
//        System.out.println("应发收入合计:"+result.get("应发收入合计"));
//        System.out.println("工会会费:"+jexlContext.get("工会会费"));
//        System.out.println("实发薪酬:"+jexlContext.get("实发薪酬"));
//        System.out.println("基本薪酬实发:"+jexlContext.get("基本薪酬实发"));
//        System.out.println("绩效薪酬实发:"+jexlContext.get("绩效薪酬实发"));
        Long endTime = System.currentTimeMillis();
        //输出：2
        System.out.println(endTime - startTime);
    }
}
